package com.tomecode.tools.maven.settings.gui.frm;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyAdapter;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.grouplayout.GroupLayout;
import org.eclipse.swt.layout.grouplayout.LayoutStyle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Dialog;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.List;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

import com.tomecode.tools.maven.settings.gui.images.ImageFactory;
import com.tomecode.tools.maven.settings.gui.utils.GuiUtils;
import com.tomecode.tools.maven.settings.gui.utils.SWTResourceManager;
import com.tomecode.tools.maven.settings.model.Proxy;

/**
 * Dialog for editing proxy
 * 
 * @author Tomas Frastia
 * @see http://www.tomecode.com or
 *      http://code.google.com/p/maven-settings-editor/
 * 
 */
public final class FrmProxy extends Dialog {

	private Proxy newProxy;
	private Shell shlProxies;
	private java.util.List<Proxy> listOfProxies;
	private Proxy existsProxy;
	private Text textId;
	private Text textUsername;
	private Text textPassword;
	private Text textProtocol;
	private Text textPort;
	private Text textHost;
	private Label labelWarning;

	/**
	 * Create the dialog.
	 * 
	 * @param parent
	 * @param style
	 */
	public FrmProxy(Shell parent, java.util.List<Proxy> listOfProxies) {
		super(parent, SWT.APPLICATION_MODAL | SWT.DIALOG_TRIM);
		setText("New Proxy");
		this.listOfProxies = listOfProxies;
	}

	/**
	 * Open the dialog.
	 * 
	 * @return the result
	 */
	public final Proxy open(Proxy exitsProxy) {
		createContents(exitsProxy);
		shlProxies.open();
		shlProxies.layout();
		Display display = getParent().getDisplay();
		while (!shlProxies.isDisposed()) {
			if (!display.readAndDispatch()) {
				display.sleep();
			}
		}
		return newProxy;
	}

	/**
	 * Create contents of the dialog.
	 */
	private final void createContents(Proxy existsProxy) {
		shlProxies = new Shell(getParent(), getStyle());
		shlProxies.setImage(ImageFactory.MAVEN_SETTINGS_EDITOR_16);
		shlProxies.setSize(600, 530);

		Composite composite = new Composite(shlProxies, SWT.NONE);
		final Button btnSave = new Button(composite, SWT.NONE);

		final Proxy resultProxy;
		if (existsProxy == null) {
			resultProxy = new Proxy();
			shlProxies.setText("New Proxy");
			btnSave.setEnabled(false);
		} else {
			resultProxy = new Proxy(existsProxy);
			shlProxies.setText("Edit Proxy");
			btnSave.setEnabled(true);
		}

		GroupLayout gl_shlProxies = new GroupLayout(shlProxies);
		gl_shlProxies.setHorizontalGroup(gl_shlProxies.createParallelGroup(GroupLayout.LEADING).add(composite, GroupLayout.DEFAULT_SIZE, 545, Short.MAX_VALUE));
		gl_shlProxies.setVerticalGroup(gl_shlProxies.createParallelGroup(GroupLayout.LEADING).add(composite, GroupLayout.DEFAULT_SIZE, 442, Short.MAX_VALUE));

		Group group = new Group(composite, SWT.NONE);

		Label lblId = new Label(group, SWT.NONE);
		lblId.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblId.setText("ID");

		textId = new Text(group, SWT.BORDER);
		textId.setText(GuiUtils.formateNull(resultProxy.getId()));
		textId.addKeyListener(new KeyAdapter() {
			@Override
			public final void keyReleased(KeyEvent e) {
				resultProxy.setId(textId.getText());
				if (resultProxy.getId().trim().length() == 0) {
					labelWarning.setText("Proxy ID can't be empty");
					btnSave.setEnabled(false);
				} else {
					if (existProxtId(resultProxy)) {
						labelWarning.setText("Proxy ID already exits");
						btnSave.setEnabled(false);
					} else {
						labelWarning.setText("");
						btnSave.setEnabled(true);
					}
				}
			}
		});

		Label labelHelpId = new Label(group, SWT.NONE);
		labelHelpId.setToolTipText("A unique identifier.");
		labelHelpId.setImage(ImageFactory.HELP);

		Label lblUsername = new Label(group, SWT.NONE);
		lblUsername.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblUsername.setText("UserName");

		textUsername = new Text(group, SWT.BORDER);
		textUsername.setText(GuiUtils.formateNull(resultProxy.getUsername()));
		textUsername.addKeyListener(new KeyAdapter() {
			@Override
			public final void keyReleased(KeyEvent e) {
				resultProxy.setUsername(textUsername.getText());
			}
		});

		Label labelHelpUsername = new Label(group, SWT.NONE);
		labelHelpUsername.setToolTipText("The proxy user.");
		labelHelpUsername.setImage(ImageFactory.HELP);

		Label lblOassword = new Label(group, SWT.NONE);
		lblOassword.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblOassword.setText("Password");

		textPassword = new Text(group, SWT.BORDER);
		textPassword.setText(GuiUtils.formateNull(resultProxy.getPassword()));
		textPassword.addKeyListener(new KeyAdapter() {
			@Override
			public final void keyReleased(KeyEvent e) {
				resultProxy.setProtocol(textProtocol.getText());
			}
		});

		Label labelHelpPassword = new Label(group, SWT.NONE);
		labelHelpPassword.setToolTipText("The proxy password.");
		labelHelpPassword.setImage(ImageFactory.HELP);

		Label lblProtocol = new Label(group, SWT.NONE);
		lblProtocol.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblProtocol.setText("Protocol");

		Label labelHelpProtocol = new Label(group, SWT.NONE);
		labelHelpProtocol.setToolTipText("The proxy protocol.");
		labelHelpProtocol.setImage(ImageFactory.HELP);

		textProtocol = new Text(group, SWT.BORDER);
		textProtocol.setText(GuiUtils.formateNull(resultProxy.getProtocol()));
		textProtocol.addKeyListener(new KeyAdapter() {
			@Override
			public final void keyReleased(KeyEvent e) {
				resultProxy.setProtocol(textProtocol.getText());
			}
		});

		Label lblPort = new Label(group, SWT.NONE);
		lblPort.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblPort.setText("Port");

		textPort = new Text(group, SWT.BORDER);
		textPort.setText(GuiUtils.formateNull(resultProxy.getPort()));
		textPort.addKeyListener(new KeyAdapter() {
			@Override
			public final void keyReleased(KeyEvent e) {
				resultProxy.setPort(textPort.getText());
			}
		});

		Label labelHelpPort = new Label(group, SWT.NONE);
		labelHelpPort.setToolTipText("The proxy port. ");
		labelHelpPort.setImage(ImageFactory.HELP);

		Label lblHost = new Label(group, SWT.NONE);
		lblHost.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		lblHost.setText("Host");

		textHost = new Text(group, SWT.BORDER);
		textHost.setText(GuiUtils.formateNull(resultProxy.getHost()));
		textHost.addKeyListener(new KeyAdapter() {
			@Override
			public final void keyReleased(KeyEvent e) {
				resultProxy.setPort(textPort.getText());
			}
		});

		Label labelHelpHost = new Label(group, SWT.NONE);
		labelHelpHost.setToolTipText("The proxy host.");
		labelHelpHost.setImage(ImageFactory.HELP);

		Group group_1 = new Group(group, SWT.NONE);

		Label labelHelpNonProxyHostList = new Label(group, SWT.NONE);
		labelHelpNonProxyHostList.setToolTipText("The list of non-proxied hosts");
		labelHelpNonProxyHostList.setImage(ImageFactory.HELP);

		final Button btnActive = new Button(group, SWT.CHECK);
		btnActive.setSelection(resultProxy.isActive());
		btnActive.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));
		btnActive.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				resultProxy.setActive(btnActive.getSelection());
			}
		});
		btnActive.setText("Active");

		labelWarning = new Label(group, SWT.NONE);
		labelWarning.setForeground(SWTResourceManager.getColor(SWT.COLOR_RED));
		labelWarning.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD | SWT.ITALIC));

		Label lblNonProxyHosts = new Label(group, SWT.NONE);
		lblNonProxyHosts.setText("Non Proxy Hosts");
		lblNonProxyHosts.setFont(SWTResourceManager.getFont("Lucida Grande", 11, SWT.BOLD));

		Label label = new Label(group, SWT.NONE);
		label.setToolTipText("Whether this proxy configuration is the active one.");
		label.setImage(ImageFactory.HELP);
		label.setFont(SWTResourceManager.getFont("Tahoma", 8, SWT.BOLD));
		GroupLayout gl_group = new GroupLayout(group);
		gl_group.setHorizontalGroup(gl_group
				.createParallelGroup(GroupLayout.LEADING)
				.add(gl_group
						.createSequentialGroup()
						.addContainerGap()
						.add(gl_group
								.createParallelGroup(GroupLayout.LEADING)
								.add(gl_group.createSequentialGroup().add(labelWarning, GroupLayout.PREFERRED_SIZE, 516, GroupLayout.PREFERRED_SIZE).addContainerGap())
								.add(gl_group
										.createSequentialGroup()
										.add(gl_group.createParallelGroup(GroupLayout.LEADING).add(lblId, GroupLayout.DEFAULT_SIZE, 107, Short.MAX_VALUE).add(lblUsername, GroupLayout.PREFERRED_SIZE, 95, GroupLayout.PREFERRED_SIZE)
												.add(lblProtocol, GroupLayout.PREFERRED_SIZE, 90, GroupLayout.PREFERRED_SIZE).add(lblPort, GroupLayout.PREFERRED_SIZE, 95, GroupLayout.PREFERRED_SIZE).add(lblOassword, GroupLayout.PREFERRED_SIZE, 89, GroupLayout.PREFERRED_SIZE)
												.add(lblHost, GroupLayout.PREFERRED_SIZE, 81, GroupLayout.PREFERRED_SIZE).add(lblNonProxyHosts))
										.addPreferredGap(LayoutStyle.RELATED)
										.add(gl_group
												.createParallelGroup(GroupLayout.TRAILING)
												.add(gl_group
														.createParallelGroup(GroupLayout.LEADING)
														.add(gl_group.createParallelGroup(GroupLayout.TRAILING, false).add(textPassword, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE).add(textUsername, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE)
																.add(textId, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE).add(textPort, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE)
																.add(textProtocol, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE)).add(textHost, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE).add(btnActive))
												.add(group_1, GroupLayout.PREFERRED_SIZE, 438, GroupLayout.PREFERRED_SIZE))
										.addPreferredGap(LayoutStyle.UNRELATED)
										.add(gl_group.createParallelGroup(GroupLayout.TRAILING)
												.add(gl_group.createParallelGroup(GroupLayout.LEADING).add(labelHelpHost).add(labelHelpId).add(labelHelpUsername).add(labelHelpPassword).add(labelHelpProtocol).add(labelHelpPort).add(labelHelpNonProxyHostList)).add(label)).add(11)))));
		gl_group.setVerticalGroup(gl_group.createParallelGroup(GroupLayout.LEADING).add(
				gl_group.createSequentialGroup()
						.addContainerGap()
						.add(gl_group.createParallelGroup(GroupLayout.BASELINE).add(textId, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).add(labelHelpId).add(lblId))
						.addPreferredGap(LayoutStyle.RELATED)
						.add(gl_group.createParallelGroup(GroupLayout.BASELINE).add(textUsername, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).add(labelHelpUsername).add(lblUsername))
						.addPreferredGap(LayoutStyle.RELATED)
						.add(gl_group.createParallelGroup(GroupLayout.BASELINE).add(textPassword, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).add(labelHelpPassword).add(lblOassword))
						.addPreferredGap(LayoutStyle.RELATED)
						.add(gl_group.createParallelGroup(GroupLayout.BASELINE).add(textProtocol, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).add(labelHelpProtocol).add(lblProtocol))
						.addPreferredGap(LayoutStyle.RELATED)
						.add(gl_group.createParallelGroup(GroupLayout.BASELINE).add(labelHelpPort).add(textPort, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).add(lblPort))
						.addPreferredGap(LayoutStyle.RELATED)
						.add(gl_group.createParallelGroup(GroupLayout.LEADING).add(gl_group.createParallelGroup(GroupLayout.BASELINE).add(textHost, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).add(lblHost)).add(labelHelpHost))
						.add(gl_group
								.createParallelGroup(GroupLayout.LEADING)
								.add(gl_group
										.createSequentialGroup()
										.add(gl_group.createParallelGroup(GroupLayout.LEADING).add(gl_group.createSequentialGroup().add(27).add(labelHelpNonProxyHostList))
												.add(gl_group.createSequentialGroup().add(7).add(group_1, GroupLayout.PREFERRED_SIZE, 203, GroupLayout.PREFERRED_SIZE))).add(18).add(gl_group.createParallelGroup(GroupLayout.LEADING).add(btnActive).add(label)))
								.add(gl_group.createSequentialGroup().addPreferredGap(LayoutStyle.UNRELATED).add(lblNonProxyHosts))).addPreferredGap(LayoutStyle.UNRELATED).add(labelWarning).addContainerGap(53, Short.MAX_VALUE)));

		final List listNonProxyHosts = new List(group_1, SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL);
		GuiUtils.fillListItem(listNonProxyHosts, resultProxy.getNonProxyHosts());
		listNonProxyHosts.addMouseListener(new MouseAdapter() {
			public final void mouseDoubleClick(MouseEvent e) {
				int index = listNonProxyHosts.getSelectionIndex();
				if (index != -1) {
					openFrmNonProxyHostForEdit(listNonProxyHosts, resultProxy, index);
				}
			}
		});
		final Button btnDelete = new Button(group_1, SWT.NONE);
		final Button btnEdit = new Button(group_1, SWT.NONE);
		listNonProxyHosts.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				btnDelete.setEnabled(listNonProxyHosts.getSelectionIndex() != -1);
				btnEdit.setEnabled(listNonProxyHosts.getSelectionIndex() != -1);
			}
		});

		Button btnDeleteAll = new Button(group_1, SWT.NONE);
		btnDeleteAll.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				resultProxy.getNonProxyHosts().clear();
				listNonProxyHosts.removeAll();
			}
		});
		btnDeleteAll.setText("Delete All");

		btnDelete.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				resultProxy.getNonProxyHosts().remove(listNonProxyHosts.getSelectionIndex());
				listNonProxyHosts.remove(listNonProxyHosts.getSelectionIndex());
			}
		});
		btnDelete.setText("Delete");

		btnEdit.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				openFrmNonProxyHostForEdit(listNonProxyHosts, resultProxy, listNonProxyHosts.getSelectionIndex());
			}
		});
		btnEdit.setText("Edit");

		Button btnAdd = new Button(group_1, SWT.NONE);
		btnAdd.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				FrmNonProxyHost frmNonProxyHost = new FrmNonProxyHost(shlProxies, resultProxy.getNonProxyHosts());
				String nonProxyHost = frmNonProxyHost.open(null);
				if (nonProxyHost != null) {
					resultProxy.addNonProxyHost(nonProxyHost);
					GuiUtils.fillListItem(listNonProxyHosts, resultProxy.getNonProxyHosts());
				}
			}
		});
		btnAdd.setText("Add");
		GroupLayout gl_group_1 = new GroupLayout(group_1);
		gl_group_1.setHorizontalGroup(gl_group_1.createParallelGroup(GroupLayout.TRAILING).add(
				gl_group_1
						.createSequentialGroup()
						.addContainerGap(28, Short.MAX_VALUE)
						.add(gl_group_1.createParallelGroup(GroupLayout.LEADING).add(GroupLayout.TRAILING, gl_group_1.createSequentialGroup().add(listNonProxyHosts, GroupLayout.PREFERRED_SIZE, 418, GroupLayout.PREFERRED_SIZE).addContainerGap())
								.add(GroupLayout.TRAILING, gl_group_1.createSequentialGroup().add(btnAdd).addPreferredGap(LayoutStyle.RELATED).add(btnEdit).addPreferredGap(LayoutStyle.RELATED).add(btnDelete).addPreferredGap(LayoutStyle.RELATED).add(btnDeleteAll).add(27)))));
		gl_group_1.setVerticalGroup(gl_group_1.createParallelGroup(GroupLayout.LEADING).add(
				gl_group_1.createSequentialGroup().add(10).add(listNonProxyHosts, GroupLayout.PREFERRED_SIZE, 136, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.RELATED)
						.add(gl_group_1.createParallelGroup(GroupLayout.BASELINE).add(btnDeleteAll).add(btnDelete).add(btnEdit).add(btnAdd)).addContainerGap()));
		group_1.setLayout(gl_group_1);
		group.setLayout(gl_group);

		Button btnCancel = new Button(composite, SWT.NONE);
		btnCancel.setText("Cancel");
		btnCancel.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				shlProxies.close();
			}
		});
		btnSave.setText("Save");
		btnSave.addSelectionListener(new SelectionAdapter() {
			@Override
			public final void widgetSelected(SelectionEvent e) {
				newProxy = resultProxy;
				shlProxies.close();
			}
		});

		GroupLayout gl_composite = new GroupLayout(composite);
		gl_composite.setHorizontalGroup(gl_composite.createParallelGroup(GroupLayout.TRAILING)
				.add(gl_composite.createSequentialGroup().addContainerGap().add(btnSave, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.RELATED).add(btnCancel).addContainerGap())
				.add(GroupLayout.LEADING, group, GroupLayout.DEFAULT_SIZE, 600, Short.MAX_VALUE));
		gl_composite.setVerticalGroup(gl_composite.createParallelGroup(GroupLayout.LEADING).add(
				gl_composite.createSequentialGroup().add(group, GroupLayout.PREFERRED_SIZE, 460, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.RELATED).add(gl_composite.createParallelGroup(GroupLayout.BASELINE).add(btnCancel).add(btnSave)).addContainerGap()));
		composite.setLayout(gl_composite);
		shlProxies.setLayout(gl_shlProxies);

	}

	private final boolean existProxtId(Proxy resultProxy) {
		for (Proxy proxy : listOfProxies) {
			if (existsProxy != null) {
				if (!existsProxy.equals(proxy)) {
					if (GuiUtils.formateNull(proxy.getId()).trim().equalsIgnoreCase(resultProxy.getId().trim())) {
						return true;
					}
				}
			} else {
				if (GuiUtils.formateNull(proxy.getId()).trim().equalsIgnoreCase(resultProxy.getId().trim())) {
					return true;
				}
			}
		}
		return false;
	}

	/**
	 * open {@link FrmNonProxyHost}
	 * 
	 * @param listNonProxyHosts
	 */
	private final void openFrmNonProxyHostForEdit(List listNonProxyHosts, Proxy resultProxy, int index) {
		FrmNonProxyHost frmNonProxyHost = new FrmNonProxyHost(shlProxies, resultProxy.getNonProxyHosts());
		String nonProxyHost = frmNonProxyHost.open(resultProxy.getNonProxyHosts().get(index));
		if (nonProxyHost != null) {
			resultProxy.getNonProxyHosts().set(index, nonProxyHost);
			GuiUtils.fillListItem(listNonProxyHosts, resultProxy.getNonProxyHosts());
		}
	}
}
